package me.sealer.ssm.service.impl;

import me.sealer.ssm.constant.ErrorCodeConstant;
import me.sealer.ssm.exception.SsmException;
import me.sealer.ssm.mapper.PermissionMapper;
import me.sealer.ssm.mapper.RoleMapper;
import me.sealer.ssm.mapper.RolePermissionMapper;
import me.sealer.ssm.model.Permission;
import me.sealer.ssm.model.PermissionExample;
import me.sealer.ssm.model.Role;
import me.sealer.ssm.model.RoleExample;
import me.sealer.ssm.model.RolePermission;
import me.sealer.ssm.model.RolePermissionExample;
import me.sealer.ssm.service.RolePermissionService;
import org.apache.shiro.util.Assert;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 功能描述： $ RolePermissionServiceImpl
 *
 * @author sealer
 * @email 1178884049@qq.com
 * @date 2019年11月28日 13时10分03秒
 */
@Service
public class RolePermissionServiceImpl implements RolePermissionService {
    private final RolePermissionMapper rolePermissionMapper;
    private final RoleMapper roleMapper;
    private final PermissionMapper permissionMapper;
    private final RoleServiceImpl roleService;

    public RolePermissionServiceImpl(RolePermissionMapper rolePermissionMapper, RoleMapper roleMapper, PermissionMapper permissionMapper, RoleServiceImpl roleService) {
        this.rolePermissionMapper = rolePermissionMapper;
        this.roleMapper = roleMapper;
        this.permissionMapper = permissionMapper;
        this.roleService = roleService;
    }

    @Override
    public List<Permission> queryPermissionsByRoleName(String roleName) {
        // query roles
        RoleExample roleExample = new RoleExample();
        roleExample.createCriteria().andNameEqualTo(roleName);
        List<Role> roles = roleMapper.selectByExample(roleExample);

        // 角色不存在， 抛异常
        if (roles.size() == 0) {
            throw new SsmException(ErrorCodeConstant.ROLE_ROLE_NOT_EXISTS, new Object[]{roleName});
        }

        // 同一角色名只能有一个角色
        Assert.isTrue(roles.size() == 1, "脏数据异常");

        Role role = roles.get(0);
        List<Permission> permissions;

        // 根据roleId 获取rolePermissions
        RolePermissionExample rolePermissionExample = new RolePermissionExample();
        rolePermissionExample.createCriteria().andRoleIdEqualTo(role.getId());
        List<RolePermission> rolePermissions = rolePermissionMapper.selectByExample(rolePermissionExample);

        // 根据rolePermission获取permissions
        PermissionExample permissionExample = new PermissionExample();
        permissionExample.createCriteria().andIdIn(rolePermissions.stream().map(RolePermission::getPermissionId).collect(Collectors.toList()));
        return permissionMapper.selectByExample(permissionExample);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyRolePermissions(String roleName, List<Integer> permissionsIds) {
        Role role = roleService.queryRoleByRoleName(roleName);
        if (role == null) {
            throw new SsmException(ErrorCodeConstant.ROLE_ROLE_NOT_EXISTS, new Object[]{roleName});
        }

        int roleId = role.getId();

        RolePermissionExample rolePermissionExample = new RolePermissionExample();
        rolePermissionExample.createCriteria().andRoleIdEqualTo(roleId);
        rolePermissionMapper.deleteByExample(rolePermissionExample);

        permissionsIds.forEach(id -> {
            RolePermission rolePermission = new RolePermission(roleId, id);
            rolePermissionMapper.insert(rolePermission);
        });
    }
}
